package ar.com.solidussource.howmuchmobile.common.utils;

import android.graphics.Point;
import ar.com.solidussource.howmuchmobile.common.entities.Geopoint;
import ar.com.solidussource.howmuchmobile.common.entities.Market;
import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapView;
import com.google.android.maps.Projection;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
 * Created with IntelliJ IDEA.
 * User: FT31270775
 * Date: 21/09/12
 * Time: 14:37
 * To change this template use File | Settings | File Templates.
 */
public class ClusterService {
    final private int MAX_PIXEL_DISTANCE = 40;

    public synchronized List<MarketCluster> generateClusters(MapView mapView, List<Market> markets){
        List<MarketCluster> marketClusters = new ArrayList<MarketCluster>();

        Object[] marketsArray = markets.toArray();

        int i=0;
        while(i < marketsArray.length){

            if(marketsArray[i] != null){

                MarketCluster marketCluster = new MarketCluster();

                Market marketI = (Market)marketsArray[i];

                marketCluster.addMaket(marketI);
                marketsArray[i] = null;

                int j=0;
                while (j < marketsArray.length){
                    Market marketJ = (Market)marketsArray[j];

                    if(marketJ != null && isAValidDistance(mapView, marketCluster, marketJ)){
                        marketCluster.addMaket(marketJ);
                        marketsArray[j] = null;
                    }
                    j++;
                }

                marketClusters.add(marketCluster);

            }
            i++;
        }

        return marketClusters;
    }

    private synchronized boolean isAValidDistance(MapView mapView, MarketCluster marketCluster, Market market){

        List<Market> markets = marketCluster.getMarkets();

        Iterator<Market> ite = markets.iterator();

        while(ite.hasNext()){
            Market market1 = ite.next();

            Double distance = getPixelDistance(mapView, market1.getAddress().getGeopoint(), market.getAddress().getGeopoint());

            if(distance.doubleValue() == MAX_PIXEL_DISTANCE || distance.doubleValue() > MAX_PIXEL_DISTANCE){
                return false;
            }
        }

        return true;
    }

    private Double getPixelDistance(MapView mapView, Geopoint globalPositioning1, Geopoint globalPositioning2){
        int x1 = getPixelPointX(mapView, globalPositioning1);
        int y1 = getPixelPointY(mapView, globalPositioning1);

        int x2 = getPixelPointX(mapView, globalPositioning2);
        int y2 = getPixelPointY(mapView, globalPositioning2);

        return MathUtils.getDistance(x1, y1, x2, y2);

    }

    private Point getPixelPoint(MapView mapView, Geopoint globalPositioning){
        Projection projection = mapView.getProjection();

        GeoPoint geoPoint = new GeoPoint((int) globalPositioning.getLatitude(), (int) globalPositioning.getLongitude());

        Point centro = new Point();
        projection.toPixels(geoPoint, centro);

        return centro;
    }

    private int getPixelPointX(MapView mapView, Geopoint globalPositioning){
        Point centro = getPixelPoint(mapView, globalPositioning);
        return centro.x;
    }

    private int getPixelPointY(MapView mapView, Geopoint globalPositioning){
        Point centro = getPixelPoint(mapView, globalPositioning);
        return centro.y;
    }

    public synchronized Geopoint getCluterGlobalPositioning(MarketCluster marketCluster){
        Geopoint globalPositioning = new Geopoint();

        List<Market> markets = marketCluster.getMarkets();
        Iterator<Market> ite = markets.iterator();

        double x = 0;
        double y = 0;

        while (ite.hasNext()){
            Market market = ite.next();

            Geopoint gp = market.getAddress().getGeopoint();
            y = y + gp.getLatitude();
            x = x + gp.getLongitude();

        }

        globalPositioning.setLatitude(new Double(y/markets.size()));
        globalPositioning.setLongitude(new Double(x/markets.size()));

        return globalPositioning;
    }

    public int getMarketAmount(MarketCluster marketCluster){
        return marketCluster.getMarkets().size();
    }

}